package com.tg.paw.ums.service.impl;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tg.paw.ums.config.WxAppProperty;
import com.tg.paw.ums.entity.Admin;
import com.tg.paw.ums.model.WxAccessTokenResult;
import com.tg.paw.ums.model.WxJsCode2SessionResult;
import com.tg.paw.ums.service.IAdminService;
import com.tg.paw.ums.service.IWxLoginService;
import com.tg.paw.common.util.JWTUtil;
import com.tg.paw.common.util.TokenData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Rubble
 * @date 2020/6/24
 */
@Slf4j
@Service
public class WxLoginServiceImpl implements IWxLoginService {

    @Value("${jwt.secretKey:123456}")
    private String secretKey;

    @Autowired
    private WxAppProperty wxAppProperty;

    @Autowired
    private StringRedisTemplate redisTemplate;


    /**
     * jscode2sessionUrl
     */
    private final String jscode2sessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid={APPID}&secret={SECRET}&js_code={JSCODE}&grant_type=authorization_code";
    /**
     * tokenUrl
     */
    private final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={SECRET}";

    @Autowired
    private IAdminService adminService;

    @Override
    public WxJsCode2SessionResult jsCode2SessionResult(String jsCode) {

        String appid = wxAppProperty.getAppid();
        String secret = wxAppProperty.getSecret();
        String url = StrFormatter.format(jscode2sessionUrl, appid,secret,jsCode);

        RestTemplate restTemplate = new RestTemplate();
        Map<String,String> params = new HashMap<>(16);
        params.put("APPID",appid);
        params.put("SECRET",secret);
        params.put("JSCODE",jsCode);

        String resultStr = restTemplate.getForObject(jscode2sessionUrl, String.class,params);
        WxJsCode2SessionResult result = JSON.parseObject(resultStr,WxJsCode2SessionResult.class);

        return result;
    }

    @Override
    public String getWxAccessToken(){
        String appid = wxAppProperty.getAppid();

        String token =  redisTemplate.opsForValue().get(appid);
        if(StringUtils.isNotEmpty(token)){
            return token;
        }

        RestTemplate restTemplate = new RestTemplate();
        Map<String,String> params = new HashMap<>(16);
        params.put("APPID",appid);
        params.put("SECRET",wxAppProperty.getSecret());

        String resultStr = restTemplate.getForObject(tokenUrl, String.class,params);
        WxAccessTokenResult result = JSON.parseObject(resultStr,WxAccessTokenResult.class);
        if(result.getErrcode()==0){
            token = result.getAccess_token();
            redisTemplate.opsForValue().set(appid,token,result.getExpires_in(), TimeUnit.SECONDS);
        }

        return token;
    }


    @Override
    public TokenData wxLogin(String openId) {

        Admin admin = adminService.getByOpenId(openId);
        if(admin==null){
            String userName = RandomUtil.randomString(10);
            Admin entity = new Admin();
            entity.setAdminName(userName);
            entity.setOpenId(openId);
            adminService.save(entity);
        }

        TokenData tokenData = JWTUtil.generateToken(admin.getAdminId(), openId,secretKey);

        return tokenData;
    }
}
